package com.xxxx.car.appointment.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxx.car.appointment.domain.Appointment;
import com.xxxx.car.appointment.domain.ServiceItem;
import com.xxxx.car.appointment.domain.StatementItem;
import com.xxxx.car.appointment.mapper.ServiceItemMapper;
import com.xxxx.car.appointment.vo.StatementVo;
import com.xxxx.car.common.constant.Constants;
import com.xxxx.car.common.utils.DateUtils;
import com.xxxx.car.common.utils.SecurityUtils;
import io.jsonwebtoken.lang.Assert;
import org.apache.commons.math3.analysis.function.Constant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xxxx.car.appointment.mapper.StatementMapper;
import com.xxxx.car.appointment.domain.Statement;
import com.xxxx.car.appointment.service.IStatementService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 结算单Service业务层处理
 * 
 * @author Huang
 * @date 2024-08-28
 */
@Service
public class StatementServiceImpl extends ServiceImpl<StatementMapper,Statement> implements IStatementService
{
    @Resource
    private StatementMapper statementMapper;
    @Resource
    private StatementItemServiceImpl statementItemService;
    @Resource
    private ServiceItemMapper serviceItemMapper;
    @Resource
    private AppointmentServiceImpl appointmentService;

    /**
     * 查询结算单
     * 
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public Statement selectStatementById(Long id)
    {
        return statementMapper.selectStatementById(id);
    }

    /**
     * 查询结算单列表
     * 
     * @param statement 结算单
     * @return 结算单
     */
    @Override
    public List<Statement> selectStatementList(Statement statement)
    {
        return statementMapper.selectStatementList(statement);
    }

    /**
     * 新增结算单
     * 
     * @param statementVo 结算单
     * @return 结果
     */
    public int insertStatement(StatementVo statementVo,Long appointmentId){
        Statement statement = new Statement();
        BeanUtils.copyProperties(statementVo,statement);
        statement.setIsDelete(Constants.DEL_FLAG_NORMAL);//默认删除状态为正常
        statement.setStatus(Statement.CONSUMER); //状态为消费中
        // 有appointmentId 就set进入
        statement.setAppointmentId(appointmentId);
        statement.setCreateTime(DateUtils.getNowDate());
        return statementMapper.insertStatement(statement);
    }

    public int insertStatementNormal(Statement statement){
        return statementMapper.insertStatement(statement);
    }

    public int insertStatement(StatementVo statementVo){
        return this.insertStatement(statementVo,null);
    }

    /**
     * 修改结算单
     * 
     * @param statementVo 结算单
     * @return 结果
     */
    @Override
    public int updateStatement(StatementVo statementVo)
    {
        Statement statement = statementMapper.selectStatementById(statementVo.getId());
        Assert.notNull(statement,"参数错误!");
        Assert.state(statement.getStatus().equals(Statement.CONSUMER),"已支付的订单不允许修改");
        BeanUtils.copyProperties(statementVo,statement);
        return statementMapper.updateStatement(statement);
    }

    /**
     * 批量删除结算单
     * 
     * @param ids 需要删除的结算单主键
     * @return 结果
     */
    @Override
    public int deleteStatementByIds(Long[] ids)
    {
        int rows = statementMapper.deleteStatementByIds(ids);
        Assert.state(rows > 0,"已支付不能删除");
        return rows;
    }

    /**
     * 删除结算单信息
     * 
     * @param id 结算单主键
     * @return 结果
     */
    @Override
    public int deleteStatementById(Long id)
    {
        int rows = statementMapper.deleteStatementById(id);
        Assert.state(rows > 0,"已支付不能删除");
        return rows;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertStatementItemList(StatementVo statementVo) {
        List<StatementItem> statementItemList = statementVo.getStatementItemList();
        Assert.state(!CollectionUtils.isEmpty(statementItemList),"请选择本次消费的服务项");
        // 结算单状态必须为消费中
        Statement thisStatement = statementMapper.selectStatementById(statementVo.getId());
        Assert.state(Statement.CONSUMER.equals(thisStatement.getStatus()),"只能修改消费中的结算单");
        // 批量处理
        // 根据itemId 批量查询 服务项
        Set<Long> serviceItemIds = statementItemList.stream().map(StatementItem::getItemId).collect(Collectors.toSet());
        Assert.state(!CollectionUtils.isEmpty(serviceItemIds),"结算单异常,结算单不能为空");
        // List<ServiceItem> serviceItemList = serviceItemMapper.selectBatchIds(serviceItemIds);
        List<ServiceItem> serviceItemList = serviceItemMapper.selectList(new QueryWrapper<ServiceItem>().in("id",serviceItemIds));
        Assert.state(!CollectionUtils.isEmpty(serviceItemList),"结算单数据异常");
        Map<Long, BigDecimal> statementItemMap = serviceItemList.stream().collect(Collectors.toMap(ServiceItem::getId, ServiceItem::getDiscountPrice));

        //1.计算总金额 总数量
        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal totalQuantity = BigDecimal.ZERO;
        for(StatementItem statementItem : statementItemList){
            BigDecimal serviceItemPrice = statementItemMap.get(statementItem.getItemId());
            totalAmount = totalAmount.add(serviceItemPrice.multiply(statementItem.getItemQuantity()).setScale(2));
            totalQuantity = totalQuantity.add(statementItem.getItemQuantity());
        }
        Statement statement = new Statement();
        statement.setId(statementVo.getId());
        statement.setTotalAmount(totalAmount);
        statement.setTotalQuantity(totalQuantity);
        statement.setDiscountAmount(statementVo.getDiscountAmount());
        statementMapper.updateStatement(statement);
        statementItemService.deleteStatementItemByStatementId(statementVo.getId());
        statementItemService.insertStatementItem(statementVo.getStatementItemList());
        return 1;
    }

    @Override
    public List<StatementItem> selectItemsById(Long statementId) {
        return statementItemService.selectStatementItemList(statementId);
    }

    @Override
    public int dePrepay(Long id) {
        // 基于 id 查询结算单对象
        Statement statement = this.selectStatementById(id);
        Assert.state(Statement.CONSUMER.equals(statement.getStatus()),"该订单已经支付");
        // 获取到当前登录的用户
        Long userId = SecurityUtils.getUserId(); //收银员 id
        int row = statementMapper.paySuccess(id,userId);
        Assert.state(row > 0,"支付失败!");
        // 判断当前订单是否有预约信息,如果有,将其状态更新为已支付
        if(statement.getAppointmentId() != null){
            row = appointmentService.updatePaySuccess(statement.getAppointmentId());
            Assert.state( row > 0,"更新预约信息状态失败");
        }
        return row;
    }

    @Override
    public Statement selectStatementByAppointmentId(Long id) {
        return statementMapper.selectOne(new LambdaQueryWrapper<Statement>().eq(Statement::getAppointmentId, id));
    }

}
